package com.jiepos.mpos.biz.user.service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.jiepos.mpos.common.constant.DBConstant.Code;
import com.jiepos.mpos.common.constant.DBConstant.Table;
import com.jiepos.mpos.common.constant.ExceptionConstant;
import com.jiepos.mpos.common.constant.SystemConstant;
import com.jiepos.mpos.common.dao.UserDao;
import com.jiepos.mpos.common.entity.App_User_InfEntity;
import com.jiepos.mpos.common.service.SystemService;
import com.jiepos.mpos.core.entity.Pagination;
import com.jiepos.mpos.core.exception.MposException;
import com.jiepos.mpos.core.service.BaseService;
import com.jiepos.mpos.core.util.IDFactoryUtil;
import com.jiepos.mpos.core.util.StringUtils;

/**
 * @ClassName: UserService
 * @Description: 用户管理服务层
 * @author 孙永
 * @date 2017年9月24日 下午1:34:36
 */
@Service
public class UserService extends BaseService{
	
	@Autowired
	private SystemService systemService;

	@Autowired
	private UserDao userDao;
	
	public Map<String, Object> getUserInfPageList(HttpServletRequest request, Pagination pagination, 
			App_User_InfEntity condition, String roleName,String ins_cd,String ins_cn_nm, Map<String, Object> map){
		/*组装查询sql*/
		StringBuffer sql = getInitSql("t1").append(",");
		sql.append("t1.user_uuid uuid, t1.login_name, t1.user_name, t6.role_uuid, t6.role_name, ")
		.append("t1.user_category || '-' || t2.code_desc user_category, ")
		.append("t1.user_st || '-' || t3.code_desc user_st, ")
		.append("t4.ins_cd, t4.ins_cd || '-' || t4.ins_cn_nm ins_cn_nm")
		.append(" FROM ")
		.append(Table.T_APP_USER_INF).append(" t1")
		.append(" LEFT JOIN ").append(Table.T_APP_CODE_LIST).append(" t2 ON t1.user_category = t2.code_val and t2.code_tp = '").append(Code.USER_CATEGORY).append("'")
		.append(" LEFT JOIN ").append(Table.T_APP_CODE_LIST).append(" t3 ON t1.user_st = t3.code_val and t3.code_tp = '").append(Code.USER_ST).append("'")
		.append(" LEFT JOIN ").append(Table.T_APP_INS_INF).append(" t4 ON t1.ins_uuid = t4.ins_uuid")
		.append(" LEFT JOIN ").append(Table.T_APP_USERROLE_INF).append(" t5 ON t1.user_uuid = t5.user_uuid")
		.append(" LEFT JOIN ").append(Table.T_APP_ROLE_INF).append(" t6 ON t5.role_uuid = t6.role_uuid")
		.append(" where t1.login_name <> ?");
		/*构造查询条件*/
		List<String> list = new ArrayList<>();
		// 不能查询自己
		list.add(String.valueOf(map.get(SystemConstant.SESSION_LOGIN_USER)));
		/*登陆账号查询条件*/
		if(!StringUtils.isBlank(condition.getLogin_name())){
			sql.append(" and t1.login_name like ?");
			list.add("%" + condition.getLogin_name() + "%");
		}
		/*真实姓名*/
		if(!StringUtils.isBlank(condition.getUser_name())){
			sql.append(" and t1.user_name like ?");
			list.add("%" + condition.getUser_name() + "%");
		}
		/*用户类别*/
		if(!StringUtils.isBlank(condition.getUser_category())){
			sql.append(" and t1.user_category = ?");
			list.add(condition.getUser_category());
		}
		/*用户状态*/
		if(!StringUtils.isBlank(condition.getUser_st())){
			sql.append(" and t1.user_st = ?");
			list.add(condition.getUser_st());
		}
		/*机构编码*/
		if(!StringUtils.isBlank(ins_cd)){
			sql.append(" and t4.ins_cd like ?");
			list.add("%" + ins_cd + "%");
		}
		/*机构名称*/
		if(!StringUtils.isBlank(ins_cn_nm)){
			sql.append(" and t4.ins_cn_nm like ?");
			list.add("%" + ins_cn_nm + "%");
		}
		/*所属角色*/
		if(!StringUtils.isBlank(roleName)){
			sql.append(" and t6.role_name like ?");
			list.add("%" + roleName + "%");
		}
		pagination.setQueryString(sql.toString());
		pagination = getInsAuthSql(request, pagination, "t1", null);
		pagination = getOrderSql(pagination, "t1");
		return userDao.getPaginationMap(pagination, "t1", list);
	}
	
	/**
	 * 根据用户代码查询详情
	 * @param uuid
	 * @return
	 */
	public Map<String, Object> getUserInfByUuid(String uuid){
		if (StringUtils.isBlank(uuid)) {
			return new HashMap<>();
		}
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT T.USER_UUID,T.INS_UUID,T.LOGIN_NAME,T.USER_NAME,T.CARD_NUMBER,T.USER_CATEGORY,T.EMAIL,T.MOBILE,T.DESCPT,T.ALIAS_NAME,")
		.append("T1.INS_CD || '-' || T1.INS_CN_NM INST_NAME")
		.append(" FROM ")
		.append(Table.T_APP_USER_INF).append(" T")
		.append(" LEFT JOIN ")
		.append(Table.T_APP_INS_INF).append(" T1")
		.append(" ON T.INS_UUID = T1.INS_UUID")
		.append(" WHERE T.USER_UUID = ?");
		List<String> list = new ArrayList<>();
		list.add(uuid);
		List<Map<String, Object>> results = userDao.queryForList(getOrderSql(sql.toString(), "T"), list);
		return results != null ? results.get(0) : new HashMap<String, Object>();
	}
	
	/**
	 * 保存用户
	 * @param entity
	 * @param map
	 */
	public void saveUserInf(App_User_InfEntity entity, Map<String, Object> map){
		entity.setRec_upd_usr_id(String.valueOf(map.get(SystemConstant.SESSION_LOGIN_USER)));
		if (!StringUtils.isBlank(entity.getUser_uuid())) {// 修改用户信息 
			App_User_InfEntity oldEntity = userDao.findByParam("user_uuid", entity.getUser_uuid());
			entity.setRec_upd_ts(new Timestamp(System.currentTimeMillis()));
			entity.setRec_id(oldEntity.getRec_id());
			entity.setRec_crt_ts(oldEntity.getRec_crt_ts());
			entity.setLast_oper_in(SystemConstant.OPER_UPDATE);
			List noChangeList = new ArrayList();
			noChangeList.add("user_uuid");
			noChangeList.add("login_name");
			noChangeList.add("password");
			noChangeList.add("user_st");
			noChangeList.add("first_login");
			noChangeList.add("check_login_count");
			userDao.update(entity, noChangeList);
		} else {// 新增角色信息
			if(isExist(entity.getLogin_name(), entity.getMobile(), null) != 0){
				throw new MposException(ExceptionConstant.USER_LOGIN_NAME_EXISTED);
			}
			entity.setRec_crt_ts(new Timestamp(System.currentTimeMillis()));
			entity.setRec_upd_ts(new Timestamp(System.currentTimeMillis()));
			entity.setUser_uuid(IDFactoryUtil.getUUID());
			entity.setLast_oper_in(SystemConstant.OPER_ADD);
			entity.setUser_st(SystemConstant.USER_ENABLED);
			entity.setPassword(StringUtils.MD5(entity.getLogin_name() + SystemConstant.INITIAL_PASSWORD));
			entity.setFirst_login(SystemConstant.USER_NOT_LOGIN);
			userDao.save(entity);
		}
	}
	
	/**
	 * 删除用户
	 * @param user_uuids
	 */
	public void deleteUserByIds(String user_uuids){
		userDao.deleteByStatus("user_uuid", user_uuids);
	}
	
	/**
	 * 验证登录名是否存在
	 * @param loginName
	 */
	public int isExist(String loginName, String phone, String userUuid){
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT 1 FROM ").append(Table.T_APP_USER_INF).append(" WHERE MOBILE = ?");
		long result = userDao.count(sql.toString(), new Object[]{phone});
		if(result > 0){
			return 1;
		}
		/*新增用户*/
		if(StringUtils.isBlank(userUuid)){
			sql = new StringBuffer();
			sql.append("SELECT 1 FROM ").append(Table.T_APP_USER_INF).append(" WHERE LOGIN_NAME = ?");
			result = userDao.count(sql.toString(), new Object[]{loginName});
			if(result > 0){
				return 2;
			}
		}
		return 0;
	}
	
	/**
	 * 用户启用停用
	 * @param user_uuids
	 * @param isLocked
	 * @param map
	 */
	public void changeUserStatus(String user_uuids, boolean isLocked, Map map){
		if(StringUtils.isBlank(user_uuids)){
			return;
		}
		/*组装更新sql*/
		StringBuffer sql = new StringBuffer();
		sql.append("UPDATE ").append(Table.T_APP_USER_INF)
		.append(" SET USER_ST = ?,")
		.append(" REC_UPD_USR_ID = ?,")
		.append(" REC_UPD_TS = SYSDATE");
		if(!isLocked){
			sql.append(",CHECK_LOGIN_COUNT = '0'");
		}
		sql.append(" WHERE USER_UUID IN ('").append(user_uuids.replaceAll(",", "','")).append("')");
		/*更新条件*/
		String userSt = isLocked ? SystemConstant.USER_DISABLED : SystemConstant.USER_ENABLED;
		String upUser = String.valueOf(map.get(SystemConstant.SESSION_LOGIN_USER));
		List<String> pramlist = new ArrayList<>();
		pramlist.add(userSt);
		pramlist.add(upUser);
		userDao.update(sql.toString(), pramlist);
	}
	
	/**
	 * 重置密码
	 * @param user_uuids
	 * @param map
	 */
	public void resetPwd(String user_uuids, Map map){
		if(StringUtils.isBlank(user_uuids)){
			return;
		}
		/*查询出需重置密码的用户*/
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT * FROM ").append(Table.T_APP_USER_INF)
		.append(" WHERE USER_UUID IN ('").append(user_uuids.replaceAll(",", "','")).append("')");
		List<App_User_InfEntity> userList = userDao.queryForListByParam(getOrderSql(sql.toString(), null));
		if(userList == null || userList.isEmpty()){
			return;
		}
		/*设置更新信息*/
		for(App_User_InfEntity user : userList){
			user.setPassword(StringUtils.MD5(user.getLogin_name() + SystemConstant.INITIAL_PASSWORD));
			user.setCheck_login_count(null);
			user.setFirst_login(SystemConstant.USER_NOT_LOGIN);
			saveCommonData(user, map, "update");
			userDao.update(user, null);
		}
	}
	
	/**
	 * 修改密码
	 * @param loginName 登陆账号
	 * @param oldPwd 原密码
	 * @param newPwd 新密码
	 */
	public void modifyPwd(String loginName, String oldPwd, String newPwd){
		if(StringUtils.isBlank(loginName) || StringUtils.isBlank(oldPwd)|| StringUtils.isBlank(newPwd)){
			throw new MposException(ExceptionConstant.USER_LOGIN_OLD_NEW_PWD_EMPTY);
		}
		App_User_InfEntity entity = getUserByLoginName(loginName);
		/*验证用户是否存在*/
		if(entity == null || StringUtils.isBlank(entity.getUser_uuid())){
			throw new MposException(ExceptionConstant.USER_LOGIN_USER_PWD_ERROR);
		}
		/*验证原密码*/
		if(!entity.getPassword().equals(StringUtils.MD5(loginName + oldPwd))){
			throw new MposException(ExceptionConstant.USER_LOGIN_OLD_PWD_ERROR);
		}
		/*验证密码长度*/
		if(SystemConstant.USER_LOGIN_PWD_LENGTH > newPwd.length()){
			throw new MposException(ExceptionConstant.USER_LOGIN_LENGTH_SIX);
		}
		/*新密码与原密码相同*/
		if(oldPwd.equals(newPwd)){
			throw new MposException(ExceptionConstant.USER_LOGIN_PWD_NEW_EQ_OLD);
		}
		/*设置新密码*/
		entity.setPassword(StringUtils.MD5(loginName + newPwd));
		entity.setFirst_login(SystemConstant.USER_LOGIN);
		saveUserInf(entity);
	}
	
	/**
	 * 根据登loginName查询用户
	 * @param loginName 登陆名
	 * @return
	 */
	public App_User_InfEntity getUserByLoginName(String loginName){
		return userDao.findByParam("login_name", loginName);
	}
	
	/**
	 * 更新用户信息
	 * @param entity
	 */
	@Async
	public void saveUserInf(App_User_InfEntity entity){
		List noChangeList = new ArrayList();
		noChangeList.add("user_uuid");
		noChangeList.add("login_name");
		userDao.update(entity, noChangeList);
	}
	
	/**
	 * 从缓存中取用户
	 * @param userId
	 * @return
	 */
	public App_User_InfEntity getEntityFormRedis(String userId){
		return systemService.getHash(SystemConstant.REDIS_USER, userId);
	}
	
	/**
	 * 存入缓存中
	 * @param userId
	 */
	public void putEntityToRedis(String userId){
		putEntityToRedis(userId, userDao.findByParam("user_uuid", userId));
	}
	
	/**
	 * 存入缓存
	 * @param loginName
	 * @param entity
	 */
	public void putEntityToRedis(String userId, App_User_InfEntity entity){
		if(!StringUtils.isBlank(userId) && entity != null){
			systemService.putHash(SystemConstant.REDIS_USER, userId, entity);
		}
	}
	
	public boolean checkLoginUser(String userId){
		App_User_InfEntity entty = getEntityFormRedis(userId);
		if(entty == null){
			return false;
		}
		return true;
	}
}
